from flask import Flask, request
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
import json,hashlib,time,datetime

# 常量
ONE_PAGE_LIST = 10
token_salt = "henda233"
token_outime = 86400 #24小时

# 处理跨越
app = Flask(__name__)
CORS(app, supports_credentials=True, resources=r"/*")
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///articles.sqlite'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 数据库
db = SQLAlchemy(app)
# 数据模型
class Article(db.Model):
    __tablename__ = "article_table"
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100))
    info = db.Column(db.String(100))
    datahtml = db.Column(db.Text(65536))
    time = db.Column(db.Date())

class User(db.Model):
    __tablename__ = "user_table"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(100))
    password = db.Column(db.String(100))
    token = db.Column(db.String(100))
    token_time = db.Column(db.String(100))


def query_article_list(page):
    article_objs = Article.query.order_by(-Article.id).all()
    article_objs.insert(0,0)
    index_min = (int(page) - 1) * ONE_PAGE_LIST + 1
    index_max = index_min + ONE_PAGE_LIST - 1
    if index_max > len(article_objs) - 1:
        index_max = len(article_objs) - 1
    return article_objs[index_min:index_max + 1]



def query_article_context(id):
    return Article.query.filter(Article.id == int(id)).first()

def spawn_token(user,password):
    return hashlib.md5((user + password + token_salt).encode("utf-8")).hexdigest(),time.time()

def verify_token(token):
    user_obj = User.query.filter(User.token == token).first()
    if user_obj:
        if time.time() - float(user_obj.token_time) <= token_outime:
            return True
    return False

@app.route("/del",methods=["POST"])
def del_article():
    try:
        token = request.json.get("token")
        id = int(request.json.get("id"))
        if verify_token(token) and id != 0:
            Article.query.filter(Article.id == id).delete()
            db.session.commit()
            db.session.close()
            data = {
                "status":200,
                "msg":"删除成功。"
            }
        else:
            data = {
                "status":420,
                "msg":"token验证失败。"
            }
    except:
        data = {
            "status":400,
            "msg":"提交参数不合法。"
        }
    return json.dumps(data)

@app.route("/manager",methods=["POST"])
def edit_create_article():
    try:
        token = request.json.get("token")
        if verify_token(token):
            try:
                datahtml = request.json.get("datahtml")
                id = int(request.json.get("id"))
                if id == 0 and datahtml:
                    title = datahtml.split(":")[1].strip("info")
                    info = datahtml.split(":")[2].split("# ")[0]
                    article = Article(title=title,info=info,datahtml=datahtml,time=datetime.datetime.now())
                    db.session.add(article)
                elif datahtml:
                    title = datahtml.split(":")[1].strip("info")
                    info = datahtml.split(":")[2].split("# ")[0]
                    article = Article.query.filter(Article.id == id).first()
                    article.datahtml = datahtml
                    article.title = title
                    article.info = info
                db.session.commit()
                db.session.close()
                data = {
                    "status":200,
                    "msg":"文章保存成功。"
                }
            except Exception as e:
                print(e)
                data = {
                    "status":400,
                    "msg":"文章保存失败。"
                }
        else:
            data = {
                "status":420,
                "msg":"token验证失败。"
            }
    except:
        data = {
            "status":400,
            "msg":"提交参数不合法。"
        }
    return json.dumps(data)

@app.route("/login",methods=["POST"])
def login():
    try:
        user = request.json.get("username")
        password = request.json.get("password")
        if user != None and password != None:
            user_obj = User.query.filter(User.username == user).first()
            if user_obj and password == user_obj.password:
                token, token_time = spawn_token(user,password)
                user_obj.token = token
                user_obj.token_time = str(token_time)
                db.session.commit()
                data = {
                    "status":200,
                    "msg":"登录成功。",
                    "token":token
                }
            else:
                data = {
                    "status":400,
                    "msg":"登录失败，用户名或密码错误。",
                    "token":""
                }
        else:
            data = {
                "status":400,
                "msg":"登录失败，用户名或密码错误。",
                "token":""
            }
    except:
        data = {
                "status":400,
                "msg":"登录失败，用户名或密码错误。",
                "token":""
            }
    return json.dumps(data)
            
@app.route("/article",methods=["GET","POST"])
def article_get():
    # 获取文章列表
    if request.method == "GET":
        try:
            page = request.args.get("page")
            if page != None:
                data = {
                        "status":None,
                        "msg":"",
                        "datas":[]
                    }
                results = query_article_list(page)
                article_json = {}
                if len(results) != 0:
                    for article_obj in results:
                        article_json["id"] = article_obj.id
                        article_json["title"] = article_obj.title
                        article_json["info"] = article_obj.info
                        data["datas"].append(article_json)
                        article_json = {}
                    data["status"] = 200
                    data["msg"] = "成功获取{}条数据。".format(len(results))
                else:
                    data["status"] = 400
                    data["msg"] = "获取数据失败，请检查page参数或者type参数是否合法。"
            else:
                data["status"] = 400
                data["msg"] = "获取数据失败，请检查page参数或者type参数是否合法。"
        except:
            data["status"] = 400
            data["msg"] = "获取数据失败，请检查page参数或者type参数是否合法。"
        return json.dumps(data)
    elif request.method == "POST":
        article_id = request.json.get("id")
        if article_id != None:
            data = {
                    "status":None,
                    "msg":"",
                    "data":{
                        "title":"",
                        "info":"",
                        "datahtml":""
                    }
                }
            result = query_article_context(article_id)
            if result != None:
                data["data"]["title"] = result.title
                data["data"]["info"] = result.info
                data["data"]["datahtml"] = result.datahtml
                data["status"] = 200
                data["msg"] = "成功获取文章id为{}的内容。".format(article_id)
            else:
                data["status"] = 400
                data["msg"] = "获取文章id为{}的内容失败。".format(article_id)
            return json.dumps(data)




app.run()